#include "tp5Region.h"
#include "LinkRegion.h"
#include "DiskXFile.h"
#include "xtprobeImageDiskXFile.h"
#include "ImageRgb.h"
#include "tp5.h"
#include <vector>



Process::Process(char *name)
{
	image_in = new ImageRgb();
  	image_in->setBOption("verbose",false);
  
  	ImageDiskXFile *image_file = new xtprobeImageDiskXFile(name,"r");
	file_name = (char*) malloc (sizeof(char)*longueur(name)+1);
	
	strcpy(file_name,name);
	image_in->loadImageXFile(image_file);

  	//on libere l'espace occupe par image_file
  	delete image_file; 
	
	root = 0;
	m_iNbRegion = 0;
	m_iNbLink = 0;
	m_iHeight = image_in->height;
	m_iWidth = image_in ->width;	
	
	
	red = Allocation();
	blue = Allocation();
	green = Allocation();
	gray = Allocation();
	m_LabelImage = Allocation();
	
	for(int j=0;j<m_iHeight;j++)
             for(int i=0;i<m_iWidth;i++)
		{       		
			red[i][j]=image_in->get(j, i)[0];
			green[i][j]=image_in->get(j, i)[1];
			blue[i][j]=image_in->get(j, i)[2];
			gray[i][j]=(red[i][j]+green[i][j]+blue[i][j])/3;
		}			
}

int **Process::Allocation()
{
	int **tab;
	tab=new int*[m_iWidth];
	

	for(int i=0;i<m_iWidth;i++)
		tab[i]=new int[m_iHeight];
	
	return tab;
}

//cette function determine le sigma mininum de region  et renvoie le numero de la liaison
int Process::detSigmaMin()
{
	int iSigmaMin=1000000;
	int iNumLiaison=0;
	for(int i=0;i<m_iNbLink;i++)
	{
		int iSigma=Graph[i]->getSigma();
		if(iSigma < iSigmaMin)
		{
			iSigmaMin=iSigma;
			iNumLiaison=i;
		}
	}
	return iNumLiaison;}

//cette fonction renvoie la plus petite variasce  
int Process::getMinvar()
{
	int iSigmaMin=1000000;
	int iNumLiaison=0;
	for(int i=0;i<m_iNbLink;i++)
	{
		int iSigma=Graph[i]->getSigma();
		if(iSigma < iSigmaMin)
		{
			iSigmaMin=iSigma;
			iNumLiaison=i;
		}
	}
	return iSigmaMin;	
}

//cette fonction 
int Process::detDiffMaxMin()
{
	int numLiaison =0;
	//int maxMin = 1000;
	Region *r1,*r2;
	for(int i = 0;i<m_iNbLink;i++){	
		r1 = Graph[i]->getRegion1();
		r2 = Graph[i]->getRegion2();
		//teste si la difference max -min est inferieure au seuil 2
		if((maxRegion(r1) - minRegion(r2)) <= m_iSeuil2){
			numLiaison = i;	
			break;
		}
		else
		if((maxRegion(r2)-minRegion(r1)) <= m_iSeuil2){
			numLiaison = i;
			break;
		}
	}
	return numLiaison;
}


int Process::getSmollestMinusMax()
{	
	int minmax =255;
	//int maxMin = 1000;
	Region *r1,*r2;
	r1 = Graph[0]->getRegion1();
	r2 = Graph[0]->getRegion2();
	if((maxRegion(r1) - minRegion(r2)) > (maxRegion(r2)-minRegion(r1)))
		minmax = maxRegion(r2)-minRegion(r1);
	else
		minmax = maxRegion(r1)-minRegion(r2);
	for(int i = 0 ;i<m_iNbLink;i++){	
		r1 = Graph[i]->getRegion1();
		r2 = Graph[i]->getRegion2();
		//teste si la difference max -min est inferieure au seuil 2
		if((maxRegion(r1) - minRegion(r2)) < minmax){
			minmax = maxRegion(r1)-minRegion(r2);
		}
		else
		if((maxRegion(r2)-minRegion(r1)) < minmax){
			minmax = maxRegion(r2)-minRegion(r1);
		}
	}
	return minmax;
}


//fonction recursive permettant de creer le graphe des liaisons

void Process::creation_Graph(Region *current)
{
	if(current==0)
		return;
	if(current->isLeaf())
	{
		int Label=current->getLabel();	//on recupère le numero de la region
		vector<int>VoisinTmp=current->getVoisin(); //et les voisins

		for(int i=0;i<int(VoisinTmp.size());i++) //pour tous les voisins
		{
			//On crée la liaison si le numero de la region courrante > à celui de la region voisine
			// => permet d'éviter d'avoir des doublons
			if(VoisinTmp[i]<Label)
			{
				
				Graph.push_back(new Link(current,RegionTmp[VoisinTmp[i]-1]));
				m_iNbLink++;
			}
		}
	}
	creation_Graph(current->filsS1());
	creation_Graph(current->filsS2());
	creation_Graph(current->filsS3());
	creation_Graph(current->filsS4());
}


void Process::printImage(ImageRgb *img, int criterion)
{	
	
	DiskXFile *image_file;
	if(criterion == 0)
	{
		char seg[] = {'_','v','a','r','_','s','e','g','m','e','n','t','e','.','p','g','m','\0'};
		image_file = new DiskXFile(newName(file_name,seg),"w");
	}
	if(criterion == 1)
	{
		char seg[] = {'_','m','e','a','n','_','s','e','g','m','e','n','t','e','.','p','g','m','\0'};
		image_file = new DiskXFile(newName(file_name,seg),"w");
	}
	if(criterion == 2)
	{
		char seg[] = {'_','m','i','n','m','a','x','_','s','e','g','m','e','n','t','e','.','p','g','m','\0'};
		image_file = new DiskXFile(newName(file_name,seg),"w");
	}
	if(criterion == 3)
	{
		char seg[] = {'_','m','a','x','_','s','e','g','m','e','n','t','e','.','p','g','m','\0'};
		image_file = new DiskXFile(newName(file_name,seg),"w");
	}
	//real *donnees = img->data;
	for(int i=0;i<m_iWidth;i++)				
		for(int j=0;j<m_iHeight;j++)
		{
			img->data[img->width*j*3 + i*3] = red[i][j];
			img->data[img->width*j*3 + 1 + i*3] = green[i][j];
			img->data[img->width*j*3 + 2 + i*3] = blue[i][j];			
		}
	
	img->updatePixmapFromData();
  	img->saveXFile(image_file);
	
	delete image_file;

}



void Process::creation_Voisin(Region *current)
{
	if(current==0)					//point d'arret
		return;

	
	if(current->isLeaf())		//si on est sur une feuille
	{
		//PRINCIPE: grace a notre labelImage, on va tester tous les pixels sur les bordures
		//et ainsi determiner tous les voisins et créer son vecteur m_Voisin
		Point p1,p2;
		//int iX1,iX2,iY2,iY1;
		bool bAjout;

		current->getCoord(&p1,&p2);
		
		int iLabelRegion2;
		vector<int>Voisin_tmp;
		Voisin_tmp.resize(0);
		
		if(p1.getord()!=0)//if(iY1!=0)	
		{
			for(int i=p1.getabs();i<p2.getabs();i++)	//on teste les pixels au dessus de la regon
			{	
				iLabelRegion2=m_LabelImage[i][p1.getord()-1];
				bAjout=true;
				for(int j=0;j<int(Voisin_tmp.size());j++)	//on test si le pixel determiner
				{						//appartient deja au voisinnage
					if(Voisin_tmp[j]==iLabelRegion2)
						bAjout=false;
				}
				if(bAjout)	//On l'ajoute s'il n'existe pas dans 
					Voisin_tmp.push_back(iLabelRegion2);//m_Voisin	
			}
			
		}

		if(p2.getord()!=m_iHeight)//if(iY2!=m_iHeight)
		{
			for(int i=p1.getabs();i<p2.getabs();i++)
			{	
				//int label=current->getLabel();
				iLabelRegion2=m_LabelImage[i][p2.getord()];
				bAjout=true;
				for(int j=0;j<int(Voisin_tmp.size());j++)
				{
					if(Voisin_tmp[j]==iLabelRegion2)
						bAjout=false;
				}
				if(bAjout)
					Voisin_tmp.push_back(iLabelRegion2);
			}
			
		
		}
		if(p1.getabs()!=0)
		{
			for(int i=p1.getord();i<p2.getord();i++)
			{	
				iLabelRegion2=m_LabelImage[p1.getabs()-1][i];
				bAjout=true;
				for(int j=0;j<int(Voisin_tmp.size());j++)
				{
					if(Voisin_tmp[j]==iLabelRegion2)
						bAjout=false;
				}
				if(bAjout)
					Voisin_tmp.push_back(iLabelRegion2);
			}
			
		
		}

		if(p2.getabs()!=m_iWidth)
		{
			for(int i=p1.getord();i<p2.getord();i++)
			{	
				iLabelRegion2=m_LabelImage[p2.getabs()][i];
				bAjout=true;
				for(int j=0;j<int(Voisin_tmp.size());j++)
				{
					if(Voisin_tmp[j]==iLabelRegion2)
						bAjout=false;
				}
				if(bAjout)
					Voisin_tmp.push_back(iLabelRegion2);
			}
			
		
		}
		current->setVoisin(Voisin_tmp);
	//}
	}
	creation_Voisin(current->filsS1());
	creation_Voisin(current->filsS2());
	creation_Voisin(current->filsS3());
	creation_Voisin(current->filsS4());}


//met a jour l'image apres la segmentation


void Process::sauvegarde_Image(Region* current)
{
	
	if(current==0 )						//Point d'arret
		return;
	int iX1,iY1,iX2,iY2,iMu,Tmp,iLabel,iNbPixel,i,Red_Mu=0,Green_Mu=0,Blue_Mu=0;
	
	if(current->isLeaf())	//verification si on est sur une feuille
	{	
		
		//appel des caracteristiques de la region 
		Point p1,p2;
		//current->getCoord(&iX1,&iY1,&iX2,&iY2);	
		current->getCoord(&p1,&p2);
		iX1 = p1.getabs();
		iY1 = p1.getord();
		iX2 = p2.getabs();
		iY2 = p2.getord();	
		//print("%d , %d, %d, %d \n",iX1,iY1,iX2,iY2);	
		current->getParameters(&iMu,&Tmp,&iNbPixel);
		iLabel= (int)current->getLabel();
		
		//if( iX2 < m_iWidth)
		for(i=(int)iX1;i<(int)iX2;i++)			//pour tous les pixels de la region
			for(int j=(int)iY1;j<(int)iY2;j++)			
				if(m_LabelImage[i][j]==iLabel)		//S'il appartiennent réelement à la region
				{
					Red_Mu+=red[i][j];			
					Green_Mu+=green[i][j];
					Blue_Mu+=blue[i][j];
				}
		
		//Calcul des valeurs moyennes des couleurs en fonction des nouvelles regions
		if(iNbPixel != 0)
		{
			Red_Mu = int(Red_Mu/iNbPixel);
			Green_Mu = int(Green_Mu/iNbPixel);
			Blue_Mu = int(Blue_Mu/iNbPixel);
		}
		
		//tests de dépassement à priori inutile
		if(Red_Mu>255)Red_Mu=255;
		if(Green_Mu>255)Green_Mu=255;
		if(Blue_Mu>255)Blue_Mu=255;
		if(Red_Mu<0)Red_Mu=0;
		if(Green_Mu<0)Green_Mu=0;
		if(Blue_Mu<0)Blue_Mu=0;
		if(iMu>255)iMu=255;
		if(iMu<0)iMu=0;

		//On actualise les tableaux des couleurs
		//if( iX2 < m_iWidth && iX1 >= 0)
		for(i=iX1;i<iX2;i++)		
			for(int j=iY1;j<iY2;j++)
				if(m_LabelImage[i][j]==iLabel)		
				{
					red[i][j]=Red_Mu;
					green[i][j]=Green_Mu;
					blue[i][j]=Blue_Mu;
					gray[i][j]=iMu;
				}
	
			
	}
	sauvegarde_Image(current->filsS1());
	sauvegarde_Image(current->filsS2());
	sauvegarde_Image(current->filsS3());
	sauvegarde_Image(current->filsS4());
}



void Process::division(Region *current, Point P1,Point P2, int criterion) {

        double dMu,dSigma=0;
	double dminmax;
	//float moy;
	int iSomme=0,NbPixel=0;
        int iX1=P1.getabs();
        int iY1=P1.getord();
        int iX2=P2.getabs();
        int iY2=P2.getord();
        

	//critere de division
	double predicate = 0;		
	
	
	for(int i=iX1;i<iX2;i++)
		for(int j=iY1;j<iY2;j++)
		{
			iSomme+=gray[i][j];
			NbPixel++;
		}
	if(NbPixel==0)
		return;

	//calcul de la moyenne	

	dMu = double(iSomme)/(NbPixel);
	
	
	//calcul de la variance
	
	for(int i=iX1;i<iX2;i++)
		for(int j=iY1;j<iY2;j++)
			dSigma+=((gray[i][j]-dMu)*(gray[i][j]-dMu));

	dSigma=dSigma/NbPixel;
	
	//calcul de la difference max - min
	
	double min=255;
	for(int i=iX1;i<iX2;i++)
		for(int j=iY1;j<iY2;j++)
		{
		   if(min>gray[i][j])			
			min=gray[i][j];
			
		}
        double max=0;
	for(int i=iX1;i<iX2;i++)
		for(int j=iY1;j<iY2;j++)
		{
		   if(max< gray[i][j])			
			max=gray[i][j];
			
		}
	dminmax = max-min;	

	current->setCoordonne(iX1,iY1,iX2,iY2);
	
	current->m_iX1 = iX1;
	current->m_iY1 = iY1;
	current->m_iX2 = iX2;
	current->m_iY2 = iY2;//,m_iMu,m_iSigma,m_iNbPixel;	
	
	current->setParameter(dMu,dSigma,NbPixel);
	
	current->m_iMu = dMu;
	current->m_iSigma = dSigma;
	current->m_iNbPixel = NbPixel;
	
	if(criterion == 0)//on se sert de la variance entre les pixels
		predicate = dSigma;
	if(criterion == 1){//critere moyenne
		predicate =  dMu;//max;//
	}
	if(criterion == 2){
		predicate = dminmax;//max;//
		if(dminmax< 0) predicate = 0;
	}
	if(criterion == 3){
		predicate = max;
	}

	if(predicate > m_iSeuil1 && (criterion == 1 || criterion == 2 || criterion == 3) && NbPixel > 20)
	{
		
                Point p(iX1+(iX2-iX1)/2,iY1+(iY2-iY1)/2);
		current->addFilsS1();
		division(current->filsS1(),P1,p,criterion);
		//print("%d , %d \n ", iX1+(iX2-iX1)/2,iY1+(iY2-iY1)/2);
                Point a(iX1+(iX2-iX1)/2,iY1);
                Point b(iX2,iY1+(iY2-iY1)/2);
		current->addFilsS2();
		division(current->filsS2(),a,b,criterion);

            
	  	Point c(iX1,iY1+(iY2-iY1)/2);
                Point d(iX1+(iX2-iX1)/2,iY2);
		current->addFilsS3();
		division(current->filsS3(),c,d,criterion);

                Point e(iX1+(iX2-iX1)/2,iY1+(iY2-iY1)/2);
               	current->addFilsS4();
		division(current->filsS4(),e,P2,criterion);

	}
	
	if(predicate > m_iSeuil1 && criterion != 1 && criterion != 2 && criterion != 3)
	{
		
                Point p(iX1+(iX2-iX1)/2,iY1+(iY2-iY1)/2);
		current->addFilsS1();
		division(current->filsS1(),P1,p,criterion);
		//print("%d , %d \n ", iX1+(iX2-iX1)/2,iY1+(iY2-iY1)/2);
                Point a(iX1+(iX2-iX1)/2,iY1);
                Point b(iX2,iY1+(iY2-iY1)/2);
		current->addFilsS2();
		division(current->filsS2(),a,b,criterion);

            
	  	Point c(iX1,iY1+(iY2-iY1)/2);
                Point d(iX1+(iX2-iX1)/2,iY2);
		current->addFilsS3();
		division(current->filsS3(),c,d,criterion);

                Point e(iX1+(iX2-iX1)/2,iY1+(iY2-iY1)/2);
               	current->addFilsS4();
		division(current->filsS4(),e,P2,criterion);

	}
	
	if(current->isLeaf())//si c'est une region valide
	{
		RegionTmp.push_back(current);
		m_iNbRegion++;		//on augmente le nombre de region

		current->setLabel(m_iNbRegion);	//chaque region est designee par une etiquette

		//Et pour tous les pixels de la region on place dans labelImage le nom de la region
		 for(int i=iX1;i<iX2;i++)
			for(int j=iY1;j<iY2;j++)
				m_LabelImage[i][j]=m_iNbRegion;
	}
}




float Process::moyenne(Point p1, Point p2)
{
	int iX1=p1.getabs();
        int iY1=p1.getord();
        int iX2=p2.getabs();
        int iY2=p2.getord();
	//float Moyenne = 0;
	int somme = 0;
	int nbp = 1;

	for(int i=iX1;i<iX2;i++)
		for(int j=iY1;j<iY2;j++)
		{
			somme+=gray[i][j];
			nbp++;
		}
	
	return somme/nbp;	
}



void Process::fusion(int iNumLiaison)
{
	int iMu,iSigma,iNbPixel;
	Region *R1=Graph[iNumLiaison]->getRegion1();		//on recupère les regions à fusionner
	Region *R2=Graph[iNumLiaison]->getRegion2();


	//On recupère les parametres de la liaison et on les places dans la region1
	Graph[iNumLiaison]->getParameters(&iMu,&iSigma,&iNbPixel);
	R1->setParameter(iMu,iSigma,iNbPixel);

	//On recupère les coordonnées des regions
	Point R1_P1,R1_P2,R2_P1,R2_P2;
	R1->getCoord(&R1_P1,&R1_P2);
	R2->getCoord(&R2_P1,&R2_P2);


	//et on place dans R1 les points extrèmes des 2 regions
	R1->setCoordonne(min(R1_P1.getabs(),R2_P1.getabs()),min(R1_P1.getord(),R2_P1.getord()),max(R1_P2.getabs(),R2_P2.getabs()),max(R1_P2.getord(),R2_P2.getord()));
	R2->setCoordonne(-1,-1,-1,-1);

	int LabelR1=R1->getLabel();
	int LabelR2=R2->getLabel();

	//On remplace dans le LabelImage tous les pixels qui correspondaient à la region2
	for(int i=R2_P1.getabs();i<R2_P2.getabs();i++)
		for(int j=R2_P1.getord();j<R2_P2.getord();j++)
			if(m_LabelImage[i][j]==LabelR2)
				m_LabelImage[i][j]=LabelR1;
	
	//mise a jour du graphe des liaisons et de son voisinnage
	// on commence par determiner le nombre de liaison à modifier 
                
	int nb_a_modifier=0,VoisinJ;

	for(int j=0;j<R1->getNbVoisin();j++)
	{
		VoisinJ=R1->getVoisin(j);
		if(VoisinJ!=LabelR2)
			nb_a_modifier++;
	}
	for(int j=0;j<R2->getNbVoisin();j++)
	{
		VoisinJ=R2->getVoisin(j);
		if(VoisinJ!=LabelR1)
			nb_a_modifier++;
	}

	//On supprime la liaison fusionné
	delete Graph[iNumLiaison];
	Graph.erase(Graph.begin()+iNumLiaison);
	m_iNbLink--;

	//On supprime le label de la region2 du vecteur voisin de la region1
	for(int i=0;i<R1->getNbVoisin();i++)
		if(R1->getVoisin(i)==LabelR2)
			R1->supVoisin(i);


	//pour toutes les liaisons du graph,
	//Si on a modifié toutes les regions qu'il fallait retucher on quitte le for

	for(int i=0;i<m_iNbLink && nb_a_modifier!=0;i++)
	{

		bool LiaisonSup=false;

		int LabelLiaison1=Graph[i]->getLabelR1();
		int LabelLiaison2=Graph[i]->getLabelR2();

		//on teste si la region supprimer :LABEL R2 est presente dans les liaisons
		//IsRegion1 correspond à la region1 de la liaison.
		//IsRegion1 correspond à la region2 de la liaison.
		bool IsRegion1=LabelR2==LabelLiaison1;
		bool IsRegion2=LabelR2==LabelLiaison2;
		bool IsRegion_Update=(LabelR1==LabelLiaison1 || LabelR1==LabelLiaison2 ||LabelR2==LabelLiaison1 ||LabelR2==LabelLiaison2);


		if(IsRegion1||IsRegion2||IsRegion_Update)
			nb_a_modifier--;


		if(IsRegion1||IsRegion2)
		{
			bool bLiaisonExistante=false;

			//Est ce que ce label existe deja (dsR1)?
			for(int j=0;j<R1->getNbVoisin();j++)
			{
				if(IsRegion2)
				{
					if(R1->getVoisin(j) == Graph[i]->getLabelR1())
						bLiaisonExistante=true;
				}
				else
				{
					if(R1->getVoisin(j)== Graph[i]->getLabelR2())
						bLiaisonExistante=true;
				}

			}
			//Si elle n'existe pas, il faut la rajouter
			if(!bLiaisonExistante)
			{
				if(IsRegion1)
				{
					Graph[i]->setLink(1,R1);
					R1->addVoisin(Graph[i]->getLabelR2());

				}
				else
				{
					Graph[i]->setLink(2,R1);
					R1->addVoisin(Graph[i]->getLabelR1());
				}
			}
			else		//la liaison existe =>il faut la supprimmer
			{

				Graph[i]->supVoisin(IsRegion1,LabelR2);
				delete Graph[i];
				Graph.erase(Graph.begin()+i);
				i--;							//on supprime une liaison=>il faut decrementer i
				m_iNbLink--;					//pour voir toutes les liaisons
				LiaisonSup=true;
			}
		}
		if(IsRegion_Update && LiaisonSup==false)	//On update la liaison si elle n'a pas été
			Graph[i]->upDate();						//supprimé
	}

}





void Process::segmentation(int iSeuil1,int iSeuil2, int criterion)
{
	
	int iNbRegion_max;
	
	
	this->m_iSeuil1=iSeuil1;
	this->m_iSeuil2=iSeuil2;
	root=new Region(); //root : racine de notre arbre :premier objet de class Region
	
	Point p (0,0);
	Point q(m_iWidth,m_iHeight);
	
	division(root,p,q,criterion);
	
	creation_Voisin(root);						
	creation_Graph(root);						
	RegionTmp.resize(0);						
	iNbRegion_max=m_iNbRegion;

	//On fusionne tant que le nombre de region est sup au seuil2
	if(criterion == 0)
	{//
		//fusion selon la variance 
		
		while(getMinvar() > m_iSeuil2 && m_iNbRegion != 0)
		{
						fusion(detSigmaMin());			//Fusion des regions avec le sigma le plus faible
			m_iNbRegion--;		
		}
	}
	if(criterion == 1)
	{//fusion selon la variance entre les regions
		while(getMinvar() > m_iSeuil2 && m_iNbRegion != 0)
		{
						fusion(detSigmaMin());	//Fusion des regions avec le sigma le plus faible
			m_iNbRegion--;		
		}
				
		
	}
	if( criterion == 2)
	{//fusion selon la difference max -min
		while(getSmollestMinusMax() < m_iSeuil2 && m_iNbRegion != 0)
		{
			fusion(detDiffMaxMin());
			m_iNbRegion--;
		}

	}
	
	if( criterion == 3)
	{//fusion par le critere nombre de regions inferieures a seuil 2
		while(getMoyenneMin()< m_iSeuil2 && m_iNbRegion != 0)
		//while(m_iSeuil2 < m_iNbRegion) // fusionne les region avec le critere max-nin < 100
		{	
			fusion(detMinMoy());
			m_iNbRegion--;
		}
	}

	//on sauvegarde l'image et on libère l'espace mémoire
	sauvegarde_Image(root);
	FreeTree(root);
	FreeGraph();	
}


int Process::getMoyenneMin()
{
	int minMean=1000;
	int iNumLiaison=0;
	for(int i=0;i< m_iNbLink;i++)
	{
		int mean = Graph[i]->getMean();
		if(mean < minMean)
		{
			minMean=mean;
			iNumLiaison=i;
			//break;
		}
	}
	//print("%d",iNumLiaison);
	return minMean;

}

int Process::detMinMoy()
{
	int minMean =1000;
	
	int iNumLiaison=0;
	for(int i= 0; i < m_iNbLink -1 ;i++)
	{
		int mean = Graph[i]->getMean();
		//print("%d ,",Graph[i]->getMean());
		if(mean < minMean)
		{
			minMean = mean;
			iNumLiaison = i;
			//break;
		}
	}
	//print("%d",iNumLiaison);
	return iNumLiaison;
}



int Process::minRegion(Region *region)
{
	Point p1,p2;
	region->getCoord(&p1,&p2);

	int iX1=p1.getabs();
        int iY1=p1.getord();
        int iX2=p2.getabs();
        int iY2=p2.getord();


	int min = 255;//gray[iX1][iY1];//((int)p1.getord(), (int)p1.getabs())[0];
	for(int x = iX1; x < iX2; x++)
		for(int y = iY1; y < iY2; y++) 
		{
		//	if (gray[y][x]) >= max) max = gray[y][x];
			if (gray[x][y] < min) min = gray[x][y];
		}
	return min;
	
}

int Process::maxRegion(Region *region)
{
	Point p1,p2;
	region->getCoord(&p1,&p2);
	int iX1=p1.getabs();
        int iY1=p1.getord();
        int iX2=p2.getabs();
        int iY2=p2.getord();
        


	int max = 0;//gray[iX1][iY1];//((int)p1.getord(), (int)p1.getabs())[0];
	
	for(int x = iX1; x < iX2; x++)
		for(int y = iY1; y < iY2; y++) 
		{
			if (gray[x][y] > max) max = gray[x][y];
		//	if (gray[y][x] <= min) min = gray[y][x];
		}
	return max;
	
}


//libere l'espace allouer par la methode allocation

void Process::freeSpace(int **space)
{
	if(space==0)
		return;
	for(int i=0;i<m_iWidth;i++)
		delete []space[i];
	
	delete []space;
	space=0;
}


void Process::freeTable()
{
	freeSpace(red);
	freeSpace(green);
	freeSpace(blue);
	freeSpace(gray);
	freeSpace(m_LabelImage);
}

//supprime l'arbre de division fusion
void Process::FreeTree(Region *current)
{
	if(current==0)
		return;
	if(current->isLeaf())
	{
		delete current;
		current=0;
		return;
	}
	FreeTree(current->filsS1());
	FreeTree(current->filsS2());
	FreeTree(current->filsS3());
	FreeTree(current->filsS4());

	delete current;
	current=0;
}

// Supprime le graphe des liaisons 

void Process::FreeGraph()
{
	for(int i=0;i<int(Graph.size());i++)
		delete Graph[i];

	Graph.resize(0);
}

//retourne un nom compose de la concatenation de oldname et additionName
char* Process::newName(char*oldname,char*additionName)
{
	//on soustrait 4 pour fairepartir les informations du type de l'image
	int l = longueur(oldname) - 4;
	int size = l + longueur(additionName) + 1; 

	char* nouveau = (char*)malloc(sizeof(char)*(l+longueur(additionName) + 1));
	int i = 0;
	for(i = 0;i<l;i++)
		nouveau[i] = oldname[i]; 
	//printf("\t%s\n",nouveau);
	for(int t=0,k=i; k< size;t++,k++)
		nouveau[k]=additionName[t];

	return (nouveau);
	
}

//retourne la longueur de la chaine d'entree

int Process::longueur(char* chaine)
{

	int k =0;
	for(k=0;chaine[k]!='\0';k++);
	
	return(k);
		
}


double Process::minMax(Point p1,Point p2)
{
	int min = gray[(int)p1.getord()][(int)p1.getabs()];//((int)p1.getord(), (int)p1.getabs())[0];
	int max = gray[(int)p1.getord()][(int)p1.getabs()];//img->get((int)p1.getord(), (int)p1.getabs())[0];
	for(int x = (int)p1.getabs(); x <= (int)p2.getabs(); x++)
		for(int y = (int)p1.getord(); y <= (int)p2.getord(); y++) {
			if (gray[y][x] >= max) max = gray[y][x];
			if (gray[y][x] <= min) min = gray[y][x];
		}
	return max-min;
}



